package priv.leetCode.thread.test2;

import java.util.Random;
import java.util.concurrent.Phaser;

/*
 * 作者：m鹏h
 * 时间；2025/1/15 15:30
 * 描述：
 **/
public class PhaserDemo {
 public static void main(String[] args) {
  final Phaser phaser = new Phaser(){
   @Override
   protected boolean onAdvance(int phase, int registeredParties) {
    //参与者数量，去除主线程
    int persons = registeredParties - 1;
    switch (phase){
     case 0:
      System.out.println("大家都到佘山站了，可以出发去佘山了，人数："+persons);
      break;
     case 1:
      System.out.println("大家都到佘山了，出发去爬山，人数："+persons);
      break;
     case 2:
      System.out.println("大家都到山顶了，开始休息，人数："+persons);
      break;

    }
    //判断是否只剩下一个主线程，如果是，返回true,代表终止
    return registeredParties ==1;
   }
  };

  phaser.register();
  final PersonTask personTask = new PersonTask();
  //3个全程参加的伙伴
  for(int i = 0;i<3;i++){

   phaser.register();
   new Thread(()->{
    try{
     personTask.step1Task();
     phaser.arriveAndAwaitAdvance();

     personTask.step2Task();
     phaser.arriveAndAwaitAdvance();

     personTask.step3Task();
     phaser.arriveAndAwaitAdvance();

     personTask.step4Task();
     phaser.arriveAndDeregister();


    }catch (InterruptedException e){
     e.printStackTrace();
    }
   }).start();
  }


  //两个在山腰半路返回
  for(int i = 0;i<2;i++){
   phaser.register();
   new Thread(()->{
    try{
     personTask.step1Task();
     phaser.arriveAndAwaitAdvance();

     personTask.step2Task();
     phaser.arriveAndAwaitAdvance();

     personTask.step3Task();
     System.out.println("伙伴【"+Thread.currentThread().getName()+"】中途山腰返回");
     phaser.arriveAndDeregister();

    }catch (InterruptedException e){
     e.printStackTrace();
    }
   }).start();
  }

  while (!phaser.isTerminated()) {
   int phase = phaser.arriveAndAwaitAdvance();
   if (phase == 2) {
    //两个在佘山直接会合
    for(int i = 0;i<2;i++){
     phaser.register();
     new Thread(()->{
      try{
       System.out.println("伙伴【"+Thread.currentThread().getName()+"】中途加入");

       personTask.step3Task();
       phaser.arriveAndAwaitAdvance();

       personTask.step4Task();
       phaser.arriveAndDeregister();

      }catch (InterruptedException e){
       e.printStackTrace();
      }
     }).start();
    }
   }
  }
 }

 static final Random random = new Random();

 static class PersonTask{
  public void step1Task() throws InterruptedException {
   String person = "伙伴【"+Thread.currentThread().getName()+"】";
   System.out.println(person+"从家出发了......");
   Thread.sleep(random.nextInt(5000));
   System.out.println(person+"到达佘山站");
  }

  public void step2Task() throws InterruptedException {
   String person = "伙伴【"+Thread.currentThread().getName()+"】";
   System.out.println(person+"出发去佘山");
   Thread.sleep(random.nextInt(5000));
   System.out.println(person+"到达佘山");
  }

  public void step3Task() throws InterruptedException {
   String person = "伙伴【"+Thread.currentThread().getName()+"】";
   System.out.println(person+"出发去爬山");
   Thread.sleep(random.nextInt(5000));
   System.out.println(person+"到达山顶");
  }

  public void step4Task() throws InterruptedException {
   String person = "伙伴【"+Thread.currentThread().getName()+"】";
   System.out.println(person+"开始休息");
   Thread.sleep(random.nextInt(5000));
   System.out.println(person+"休息结束，下山回家");
  }
 }
}

/**
 * 伙伴【Thread-3】从家出发了......
 * 伙伴【Thread-1】从家出发了......
 * 伙伴【Thread-2】从家出发了......
 * 伙伴【Thread-4】从家出发了......
 * 伙伴【Thread-0】从家出发了......
 * 伙伴【Thread-1】到达佘山站
 * 伙伴【Thread-4】到达佘山站
 * 伙伴【Thread-3】到达佘山站
 * 伙伴【Thread-0】到达佘山站
 * 伙伴【Thread-2】到达佘山站
 * 大家都到佘山站了，可以出发去佘山了，人数：5
 * 伙伴【Thread-3】出发去佘山
 * 伙伴【Thread-2】出发去佘山
 * 伙伴【Thread-4】出发去佘山
 * 伙伴【Thread-1】出发去佘山
 * 伙伴【Thread-0】出发去佘山
 * 伙伴【Thread-1】到达佘山
 * 伙伴【Thread-4】到达佘山
 * 伙伴【Thread-3】到达佘山
 * 伙伴【Thread-0】到达佘山
 * 伙伴【Thread-2】到达佘山
 * 大家都到佘山了，出发去爬山，人数：5
 * 伙伴【Thread-1】出发去爬山
 * 伙伴【Thread-4】出发去爬山
 * 伙伴【Thread-0】出发去爬山
 * 伙伴【Thread-2】出发去爬山
 * 伙伴【Thread-3】出发去爬山
 * 伙伴【Thread-6】中途加入
 * 伙伴【Thread-6】出发去爬山
 * 伙伴【Thread-5】中途加入
 * 伙伴【Thread-5】出发去爬山
 * 伙伴【Thread-2】到达山顶
 * 伙伴【Thread-5】到达山顶
 * 伙伴【Thread-0】到达山顶
 * 伙伴【Thread-4】到达山顶
 * 伙伴【Thread-4】中途山腰返回
 * 伙伴【Thread-6】到达山顶
 * 伙伴【Thread-3】到达山顶
 * 伙伴【Thread-3】中途山腰返回
 * 伙伴【Thread-1】到达山顶
 * 大家都到山顶了，开始休息，人数：5
 * 伙伴【Thread-5】开始休息
 * 伙伴【Thread-2】开始休息
 * 伙伴【Thread-6】开始休息
 * 伙伴【Thread-0】开始休息
 * 伙伴【Thread-1】开始休息
 * 伙伴【Thread-2】休息结束，下山回家
 * 伙伴【Thread-0】休息结束，下山回家
 * 伙伴【Thread-1】休息结束，下山回家
 * 伙伴【Thread-5】休息结束，下山回家
 * 伙伴【Thread-6】休息结束，下山回家
 */


